﻿// Inner Fire 游戏引擎库
// Transform - 游戏变形对象
//
// Copyright (c) 2025 by 尔西大帝. All rights reserved.
//
// 所属层级：应用层（4）
// 指定对象的Position，Scale，Rotation的项目。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2025-01-21

#pragma once

#include <graphics/imath.h>

namespace ifire::game {
class GameObject;

struct Transform {
  Transform(GameObject* owner);
  ~Transform() = default;

  // 绑定的GameObject
  GameObject* game_object;
  // 父级
  Transform* parent;

  // 此节点的变换矩阵
  IMat mat;

  // 在世界空间中的位置
  IVec3 position;
  // 在世界空间中的缩放
  IVec3 scale;
  // 在世界空间中的旋转（使用四元数表示）
  IVec4 rotation;

  // 得到位置
  IVec3 GetPosition() const;
  IVec4 GetRotation() const;
  // 得到旋转(用欧拉角（角度）表示）
  IVec3 GetRotationEular() const;
  // 得到缩放
  IVec3 GetScale() const;

  // 设置位置
  void SetPosition(const IVec3& value);
  // 设置旋转。值为欧拉角，单位为角度数，而非弧度数
  void SetRotationEular(const IVec3& value);
  // 设置缩放
  void SetScale(const IVec3& value);
  // 创建世界矩阵
  IMat BuildMatrix();
  // 通过位移、旋转（欧拉角，单位角度），缩放来设置当前的矩阵。不考虑层级关系。
  IMat SetWorldMatrix(
      const IVec3& position, const IVec3& rotation, const IVec3& scale);
  // 直接通过一个世界矩阵来设置当前的Transform
  void SetWorldMatrix(FMat mat);
  // 将一个方向变换为以此矩阵所在空间为准的向量。
  IVec3 TransformDirection(const IVec3& direction) const;
  // 将一个顶点转换为世界空间（包括平移）
  IVec3 TransformPosition(const IVec3& position) const;
  // 当一个方向向量转为以Forward为照向的向量
  IVec3 TransformForward(IVec3 vec) const;
  // 将一个世界坐标转为本地坐标
  IVec3 WorldToLocal(IVec3 world_position) const;

  // 使这个对象向一个方向向量旋转，可以指定delta，表示最次最多旋转角度，返回值为当前旋转角度
  IVec3 LookTowardLerp(const IVec3& direction, float max_delta_angle);

  // 将此项目设置为从开始点到结束点的一个弹簧
  void SetSpring(IVec3 start, IVec3 end, float width = 1.0f);

  IVec3 GetForward() const;
  IVec3 GetParentPosition() const;
  IVec4 GetParentRotation() const;
  IVec3 GetParentScale() const;
};

} // namespace ifire::game